﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Mimoza.ObjectLayer;
using Mimoza.PluginLayer;
using Mimoza.Apps.Console.ViewModel;
using Mimoza.Apps.Console.Commands;
using Mimoza.Apps.Console.Resources;


namespace Mimoza.Apps.Console.View
{    
    public partial class PolicyView : BaseView
    {
        private ImageList m_smallIcons = new ImageList();
        private ImageList m_largeIcons = new ImageList();
        private Dictionary<string, int> m_iconsKey = new Dictionary<string, int>();


        public PolicyView()
        {
            InitializeComponent();
        }
        public override void Init(BaseViewModel viewModel)
        {
            m_viewModel = viewModel;

            m_smallIcons.ImageSize = new Size(16, 16);
            m_largeIcons.ImageSize = new Size(32, 32);

            m_smallIcons.Images.Add(new Icon(Resource.DefaultPolicyIcon, m_smallIcons.ImageSize));
            m_largeIcons.Images.Add(new Icon(Resource.DefaultPolicyIcon, m_largeIcons.ImageSize));

            int index = 1;
            foreach (IConfigPlugin plugin in this.m_viewModel.Application.PluginManager.Plugins)
            {
                if (null != plugin.Icon)
                {
                    string[] pluginIds = Common.ArrayToString.FromString(plugin.Identity);
                    foreach (string pluginId in pluginIds)
                    {
                        m_iconsKey.Add(pluginId, index);
                        m_smallIcons.Images.Add(new Icon(plugin.Icon, m_smallIcons.ImageSize));
                        m_largeIcons.Images.Add(new Icon(plugin.Icon, m_largeIcons.ImageSize));
                        index++;
                    }
                }
            }

            this.Dock = DockStyle.Fill;
            this.listView.ContextMenuStrip = this.contextMenuStrip;
            this.listView.SmallImageList = m_smallIcons;
            this.listView.LargeImageList = m_largeIcons;

            m_viewModel.PropertyChanged += new PropertyChangedEventHandler(PolicyViewModel_PropertyChanged);
            m_viewModel.OnObjectChanged += new EventHandler<ObjectLayer_ObjectChangedEventArgs>(PolicyViewModel_OnObjectChanged);

            AddCommand2Context(m_viewModel, this.contextMenuStrip);
            FillPolicy();
        }

        private void FillPolicy()
        {
            Mimoza.ObjectLayer.Container cont = (m_viewModel as Mimoza.Apps.Console.ViewModel.PolicyViewModel).CurrentContainer;

            listView.Items.Clear();
            if (null != cont)
            {
                if (null != cont.Parent)
                {
                    foreach (Mimoza.ObjectLayer.Policy policy in cont.Parent.GetEffectivePolicy())
                    {
                        InsertPolicy(policy);
                    }
                }
                foreach (Mimoza.ObjectLayer.Policy policy in cont.GetDirectPolicy())
                {
                    InsertPolicy(policy);
                }
            }
        }

        private void InsertPolicy(Mimoza.ObjectLayer.Policy policy)
        {
            Mimoza.ObjectLayer.Container cont = (m_viewModel as Mimoza.Apps.Console.ViewModel.PolicyViewModel).CurrentContainer;

            int groupIndex = -1;
            if (null != cont.Parent)
            {
                foreach (Mimoza.ObjectLayer.Policy p in cont.Parent.GetEffectivePolicy())
                {
                    if (p.ID == policy.ID)
                    {
                        groupIndex = 0;
                        break;
                    }
                }
            }
            if (groupIndex != 0)
            {
                foreach (Mimoza.ObjectLayer.Policy p in cont.GetDirectPolicy())
                {
                    if (p.ID == policy.ID)
                    {
                        groupIndex = 1;
                        break;
                    }
                }
            }

            if (groupIndex == -1)
            {
                return;
            }

            ListViewItem item = new ListViewItem();
            ListViewItem.ListViewSubItem sub1 = new ListViewItem.ListViewSubItem();
            ListViewItem.ListViewSubItem sub2 = new ListViewItem.ListViewSubItem();
            ListViewItem.ListViewSubItem sub3 = new ListViewItem.ListViewSubItem();

            item.Tag = policy;
            item.Text = policy.Name;
            item.Name = policy.Name;
            item.Group = listView.Groups[groupIndex];
            item.ImageIndex = 0;
            if (groupIndex == 0)
            {
                item.ForeColor = Color.LightGray;
            }
            if (m_iconsKey.ContainsKey(policy.PluginID))
            {
                item.ImageIndex = m_iconsKey[policy.PluginID];
            }

            IConfigPlugin plugin = this.m_viewModel.Application.PluginManager.GetConfigPlugin(policy.PluginID);
            if (null != plugin)
            {
                sub1.Text = plugin.Name;
            }
            else 
            {
                sub1.Text = "Wrong pluginID:" + policy.PluginID;
            }

            //if (policy.IsHardware)
            //{
            //    sub1.Text = Resource.PolicyView_HardwarePolicy;
            //}
            //else
            //{
            //    sub1.Text = Resource.PolicyView_SoftwarePolicy;
            //}

            if (!policy.IsEnabled)
            {
                sub2.Text = Resource.PolicyView_Yes;
            }
            else
            {
                sub2.Text = Resource.PolicyView_No;
            }

            if (policy.Override)
            {
                sub3.Text = Resource.PolicyView_Yes;
            }
            else
            {
                sub3.Text = Resource.PolicyView_No;
            }

            item.SubItems.Add(sub1);
            item.SubItems.Add(sub2);
            //item.SubItems.Add(sub3);

            listView.Items.Add(item);
        }
        private void UpdatePolicy(Mimoza.ObjectLayer.Policy policy)
        {
            FillPolicy();
        }
        private void DeletePolicy(Mimoza.ObjectLayer.Policy policy)
        {
            foreach (ListViewItem item in listView.Items)
            {
                if ((item.Tag as Policy).ID == policy.ID)
                {
                    listView.Items.Remove(item);
                    break;
                }
            } 
        }

        private void PolicyViewModel_OnObjectChanged(object sender, ObjectLayer_ObjectChangedEventArgs e)
        {
            Mimoza.ObjectLayer.Policy policy = e.Object as Mimoza.ObjectLayer.Policy;
            switch (e.EventType)
            {
                case ObjectLayerEventType.ObjectInserted:
                    Action<Mimoza.ObjectLayer.Policy> action = InsertPolicy;
                    Invoke(action, policy);
                    break;
                case ObjectLayerEventType.ObjectUpdated:
                    Action<Mimoza.ObjectLayer.Policy> actionUpdate = UpdatePolicy;
                    Invoke(actionUpdate, policy);
                    break;
                case ObjectLayerEventType.ObjectDeleted:
                    Action<Mimoza.ObjectLayer.Policy> actionDelete = DeletePolicy;
                    Invoke(actionDelete, policy);
                    break;
            }
        }

        private void PolicyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "CurrentContainer")
            {
                FillPolicy();
            }
        }

        private void listView_Enter(object sender, EventArgs e)
        {
            m_viewModel.InFocus = true;
        }
        private void listView_Leave(object sender, EventArgs e)
        {
            m_viewModel.InFocus = false;
        }
        private void listView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (listView.SelectedItems.Count != 0)
            {
                if (m_viewModel != null)
                {
                    m_viewModel.Context = listView.SelectedItems[0].Tag;
                }
            }
        }

        private void listView_DoubleClick(object sender, EventArgs e)
        {
            if (m_viewModel.ContextCommands == null) return;

            foreach (BaseConsoleCommand cmd in m_viewModel.ContextCommands)
            {
                if (cmd != null && cmd.Enabled && cmd.IsDefault)
                {
                    cmd.Execute();
                    return;
                }
            }
        }
    }
}
